home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Environments
/
CGIshell 1.3.2
/
documentation
/
shell-docs.txt
Wrap
Text File
|
1996-04-23
|
18KB
|
567 lines
CGI shell, version 1.3.2
(This document replaces the old documentation for versions 1.1, 1.2, 1.3,1.3.1)
This documentation, the software it describes, and the source code included
with this package is:
Copyright, Ronald T. Kneusel, 1995, 1996. All Rights Reserved.
rkneusel@post.its.mcw.edu
Distribution permitted if the entire archive is intact. If you want to
put this on CD-ROMs then you need to contact me first.
---------------------------------------------------------------------------------
WHAT'S NEW
1.3.2 (23-Apr-96): Rewrote @Field to make it more stable.
1.3.1 (17-Apr-96): Added #digits variable to control number of decimal places
when !val stores a floating point number. Default 6.
---------------------------------------------------------------------------------
*****************************
* *
* INTRODUCTION *
* *
*****************************
DISCLAIMER
This is a tool for programmers; Forth programmers in particular. Therefore,
this documentation is intentionally sparse. After all, real programmers don't
need no steenkin' documentation, right? :)
WHAT IS IT?
CGI shell works with Chris Heilman's Pocket Forth programming language to
provide a skeleton for creating custom CGI applications for WebSTAR/MacHTTP.
The shell code handles AppleEvents, the interpretation of forms data, and
supplies a set of words for building a reply string. Pocket Forth, version 6.5
is included in the release.
WHAT DO I NEED TO RUN IT?
• A Mac running WebSTAR (commercial) or MacHTTP (shareware)
• This code
• A text editor (Teachtext or Simpletext will do in a pinch)
• Some Forth and HTML programming experience
ABOUT THE SHELL SOURCE CODE
There are two layers to the shell code. The file SERVER.4TH contains
a minimal web server interface. Only the simplest of CGI applications will
use this file alone. The second, more powerful, layer is contained in the
files: STRING.4TH, FIELD.4TH, and TEMPLATE.4TH. Unless the CGI you wish to
create is exceedingly simple it is best to use the SHELL.4TH file as it contains
all the files above in the proper order.
The remainder of this file is split into two parts: SERVER.4TH and SHELL.4TH
which describe the low-level and high-level interface code respectively.
CONTENTS
• Part 1 -- Low level routines
• Part 2 -- High level routines
================================================================================
*************************************
* *
* Part 1 SERVER.4TH - low level *
* *
*************************************
A FIRST EXAMPLE
A minimal CGI using the SERVER.4TH file alone is:
\ Simple CGI
--> server.4th ( load only the minimal CGI code )
message[ s1 You are: ] ( strings used in the reply )
message[ s2 <br>Using: ]
message[ s3 <br>And your favorite flavor is: ]
message[ fname flavor] ( name of the field )
512 String>> out ( return string goes here, 512 char max )
out newstr ( clear it )
,s sdoc ,s WWWΩ ae: ( begin the AppleEvent reply handler )
out startstring ( add HTML header )
s1 out strcpy ( add 'You are: ' )
out APPEND @Addr ( add client's IP address )
s2 out strcpy ( add '<br>Using: ' )
out APPEND @Browser ( add browser type )
s3 out strcpy ( add '<br>And your favorite flavor is: ' )
out fname APPEND @Field ( add flavor field data )
out endstring ( add HTML ending )
out REPLY bye ( send the reply and quit )
;ae ( end reply handler )
This CGI will respond to an HTML form like this one:
<h1> Simple CGI test </h1>
<form method=post action="simple.cgi">
What is your favorite ice cream flavor?
<select name="flavor"
<option>Vanilla <option>Chocolate <option>Strawberry
</select>
<input type=submit value="Send it">
</form>
To create 'simple.cgi' load the Forth code above into a *copy* of Pocket Forth
and then enter save bye to save the dictionary. Use a web browser to bring
up the HTML file, call it 'simple.html', and click 'send it'. If all went well
you will receive a reply indicating who you are, what you are using, and
(presumably) your favorite type of ice cream.
MAIN USER LEVEL WORDS
The most important words defined by SERVER.4TH are @Direct, @Addr, @Browser,
and @Field. These words fetch information sent by the web server to the CGI
application.
@Direct (e.g. out APPEND @Direct )
Direct returns the direct argument attached to the action component of the
form definition. If the HTML file contains:
<form method=post action="my.cgi$3.141592">
Then the phrase out APPEND @Direct will append the string 3.141592 to
the string contained in out . If NEW is specified in place of APPEND
the direct argument replaces the previous contents of the string. All
strings are terminated with a '\0' character.
@Addr (e.g. out APPEND @Addr )
Addr returns the IP address string of the client. If the address has a
DNS entry its name will be returned. If there was no DNS entry the reversed
in-arpa numerical IP address is returned. NEW and APPEND work as above.
@Browser (e.g. out NEW @Browser )
Browser returns a string indicating what type of web browser the client
is using. This can be useful for deciding when to return a graphically
intensive page and when not to. @Browser works as @Addr and @Direct.
@Field (e.g. out f1 APPEND @Field )
Field places the contents of the field whose name is in the string f1
into the string out . NEW and APPEND work as before. @Field will handle
all translation of characters.
REPLY (e.g. out REPLY )
REPLY returns the string on the stack to the web server which then sends
it down to the client. This word must be called only from within a
ae: ... ;ae pair.
SETTING UP THE APPLE EVENT HANDLER
The heart of a CGI application is the AppleEvent handler that responds to the
AppleEvent sent by the web server. In Pocket Forth an AppleEvent handler is
first defined and then saved to the dictionary. When the application is then
launched the handler is added to the list of handlers and the application
will respond to the event whenever it is listening for events. Pocket Forth
listens to system events when waiting for input so it is unnecessary to
be concerned about handling local events (i.e. mouse clicks, keypresses, etc.)
In fact, Pocket Forth can be used normally while still listening for
AppleEvents. If you write the CGI to quit when finished you do not need to
write any code for dealing with the server Mac. This is unlike the C based
Responder CGI shell.
In Pocket Forth an Apple Event handler is defined using ae: and ;ae,
,s sdoc ,s WWWΩ ae: \ begin the handler for the sdoc,WWWΩ event
...some code here...
;ae
The general process, then, is:
,s sdoc ,s WWWΩ ae:
<get data from the apple event using @Direct, @Field, etc.>
<manipulate the data and create an output string>
<reply to the event with <output-string> REPLY>
<quit or re-initialize the application>
;ae
See the included examples for more information.
STRING SUPPORT WORDS
The CGI shell provides a number of words for manipulating null terminated
strings. These are summarized below:
message[ ( compile: <name> <text>] )
( run: -- address )
Create <name>, a null terminated string. E.g.
message[ s0 <h1>Result...</h1>]
String>> ( size -- (<name>) )
Create a string, <name>, <size> bytes long. E.g.
512 String>> theReply
strcpy ( s1 s2 -- )
Append s1 to s2. Appending is useful for creating reply
strings, use strncpy to avoid appending.
length ( s -- n )
Return the length of string s.
newstr ( s -- )
Zero the string s. Equal to 0 s c!
0type ( s -- )
Type the null terminated string s on the screen. Useful for
debugging.
accept ( s length -- )
Identical to expect but adds a terminating '\0'.
startstring ( s -- )
Add <HTML> to the string s.
endstring ( s -- )
Append </HTML> to the string s.
NUMERICAL CONVERSION
Pocket Forth has complete support for floating point numbers making it useful
for scientific applications. These words will convert between floating point
numbers and strings.
f>str ( f s -- )
Put the floating point number f into the string using the current
settings for FIX or SCI.
str>f ( s -- f )
Make s into a floating point number on the stack.
*************************************
* *
* Part 2 SHELL.4TH - high level *
* *
*************************************
This is where the real power lies. The code in SHELL.4TH allows you to create
an external file with all the HTML to be returned and to place markers in the
file to indicate where to substitute values (strings or numbers). This
separates the HTML source from the program itself and allows you to alter the
appearance without recompiling the application. It also save valuable
dictionary space by not including a lot of text.
Say we have a web page that looks like this:
<form method=post action="ftest.cgi">
Name? <input type="text" name="name"><p>
Age? <input type="text" name="age"><p>
Weight? <input type="text" name="weight">
<p><input type=submit value="Go">
</form>
This creates a form that asks for three values:
- a name (a string)
- an age (an integer)
- a weight (floating point)
It then calls a CGI application named 'ftest.cgi' which looks like this:
\ simple CGI
--> shell.4th \ load CGI shell code
$[ file ftest.txt] \ name of HTML code file
2048 String>> out \ reply goes in here
STR 80 " name" #field f1 \ define the name field
INT 15 " age" #field f2 \ and the age field
FP 20 " weight" #field f3 \ and the weight field
STR 80 " a_string" #object s1 \ plus an extra string (no reason)
message[ ss Get a life, Bozo!] \ a constant string
,s sdoc ,s WWWΩ ae: \ start the AppleEvent reply
<getFields> \ automatically load field data
ss s1 !val \ put the text in the s1 object
out file NEW template \ call template to fill in reply
out REPLY \ send the reply
bye \ and quit
;ae
Which uses the template word to read the file 'ftest.txt':
<body bgcolor="#ffffff">
<font color="#ff0000">
<h1>The Big Cheese</h1>
<hr><font size=+2 color="#339944">
You are: <b>`name`</b> <p>
You are <b>`age`</b> years old. <p>
You weigh <b>`weight`</b> pounds.
</font>
<h2>`a_string`</h2>
Notice the values in ` (backquotes)? These are the names of the fields
and objects which will have their values substituted in the reply.
WHAT'S THIS 'FIELD' AND 'OBJECT' BUSINESS?
There is only one difference between a FIELD and an OBJECT: fields are
automatically entered in the field array upon their definition. This
array is used by <getFields> to load the field data from the Apple Event.
Almost all of your CGIs will start with a call to <getFields>.
There is a second array, called the template array, which holds pointers to
all the items that are within the backquotes in the template file.
Fields are entered in this array, as are objects, when they are defined.
Three types of Objects/Fields exist: string, integer, and float. The
general memory structure for an object is:
+----+--------+-----------+---------------+
|type| name | value ... | text ........ |
+----+--------+-----------+---------------+
where:
type (1 byte) = 0 STR, 1 INT, 5 FP
name (30 bytes) = null terminated text of field name
value (0,2,10 bytes) = value of field, for STR is same as start of text,
2 bytes for INT, 10 bytes for FP
text (varies) = text string of value, i.e. INT is 2 then text is "2"
When the fields are loaded from the Apple Event they are automatically
filled in according to their type. Values stored in the field are also
automatically stored as the proper type (for Forth) and as a text string
(for the web server).
The template handles looking up names in the template file and
substituting the right text, you do not need to be at all concerned about
it. This is a big improvement over the array fiddling necessary in the
previous version.
USING OBJECTS/FIELDS
Part of the goal in this new version is to make transparant the necessary
switching between numerical values and strings. The other major goal was
to remove the array fiddling and let the programmer have easy access to
the template file.
Let's define a field:
FP 20 " spin" #field sp ( spin quantum number )
We have created a field named 'spin' that acts like a variable, i.e.
referencing sp returns the address of the beginning of the field. So,
what is it:
FP -- floating point field
20 -- string part is 20 characters long (no bounds checks!)
" spin" -- the name part is 'spin'
sp -- the dictionary name (Forth) for this object
The parts of the record are accessed via:
sp .type -- push field type on the stack (0=STR,1=INT,5=FP)
sp .name -- push address of beginning of name field on stack
sp .val -- address of value part
sp .text -- address of the text part
Values are read from and written to the field from within the program by:
@val -- return the current value of the field:
-- address of text part if it is a string
-- 16-bit integer if of type INT
-- floating point number if of type FP
!val -- store in the current record, if string then copy, if a
number then store in value part and then store a string
of the number in the text part.
** Note: The number of decimal places !val uses when storing a floating
point number is determined by the value of the variable #digits
The default is 6, 3 #digits ! would set it to three.
Example, using the field above:
1.5 sp !val
( put 1.5 in the value part and "1.5" in the string part)
sp @val 2.0 f* f.
( get the value part, 1.5, and multiply by 2, prints 3.0)
This transparent conversion between string and number when coupled with
the automatic initialization and substitution of values is what makes the
full CGI shell useful.
TEMPLATES
The word TEMPLATE accepts an output string and a file name. It then
reads the file into the output string substituting the text part of
FIELDs and OBJECTs whose names are delimited within the file by `
(backquotes).
Unlike the previous version of the CGI shell, there is nothing else for
the programmer to do. TEMPLATE does all the searching for matches between
the name read from the file and the names of fields and objects that were
stored when defined.
Specifically:
template ( output-string-address filename-addr NEW|APPEND )
-1 0
NEW and APPEND are constants defined in SERVER.4TH. If NEW the output
string is cleared before use, if APPEND the template file is appened to
the end of the existing string.
The filename string *MUST* be defined with the word $[ as it needs to be
a counted string and not a null terminated string:
$[ f1 ftest.txt] \ ] ends the text, no spaces
2048 String>> out \ a 2k output buffer
out f1 NEW template \ fill the string with the text in ftest.txt
It's that easy! Look at the included sample code to learn more.
=================================================================================
NOTES
The best way to learn to use the shell is to experiment. See the 'Deflect'
example to learn how to force the client's browser to another URL. When
developing a CGI keep the following in mind:
* turn off the processor cache if using an '040 based Mac. Some code will
compile with it on but often the application quits part way through. The
compiled code runs just fine with the cache on.
* always use a fresh copy of the Pocket Forth application when re-compiling.
* remember to do save bye after loading the code. Amazing how many times
I forget to do that!
The software carries no warranty of any kind. If it blows up and kills
your hard drive, don't come whining to me about it. (It won't, no worries :)
Caveat Emptor.
Ron Kneusel
8725 West Burdick Ave.
Milwaukee, WI 53227 USA
(414) 545-7557
rkneusel@post.its.mcw.edu
The latest version of CGIshell can always be found at:
http://kreeft.intmed.mcw.edu/pf.html
ftp://kreeft.intmed.mcw.edu/q/pub/forth/
March 1996, AMDG